home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / doom / quake2.zip / MDL23DS.ZIP / 3DS.C next >
C/C++ Source or Header  |  1996-08-20  |  5KB  |  211 lines

  1.     // move fp to end of chunk after ALL chunk writes
  2. #include "3ds.h"
  3.  
  4.   #define MAGIC     0x4D4D
  5.   #define VERSION   0x0002
  6.   #define MESH      0x3D3D
  7.    #define OBJECT    0x4000
  8.     #define HIDDEN    0x4010
  9.     #define TRIOBJ    0x4100
  10.      #define VERTS     0x4110
  11.      #define FACES     0x4120
  12.      #define TVERTS    0x4140
  13.  
  14. dword start_chunk  ( FILE *fp, word chunk_id );
  15. word  end_chunk    ( FILE *fp, dword location );
  16. word  write_ver    ( FILE *fp, dword ver );
  17. word  write_mesh   ( FILE *fp, mdl_object *obj );
  18. word write_object  ( FILE *fp, mdl_object *obj, dword findex );
  19. word write_triobj  ( FILE *fp, mdl_object *obj, dword findex );
  20. word write_verts   ( FILE *fp, mdl_object *obj, dword findex );
  21. word write_faces   ( FILE *fp, mdl_object *obj ); // obj only have one set
  22. word write_tverts  ( FILE *fp, mdl_object *obj ); // only one set
  23.  
  24. dword start_chunk ( FILE *fp, word chunk_id ) {
  25. dword location;
  26.   location = ftell(fp);
  27.  fwrite(&chunk_id,2,1,fp);
  28.  fseek(fp,4,SEEK_CUR); // skip length
  29. return location; }
  30.  
  31. word  end_chunk    ( FILE *fp, dword location ) {
  32. dword length;
  33.  
  34.  length = ftell(fp)-location; // current - start
  35.  fseek(fp,location+2,SEEK_SET);
  36.  fwrite(&length,4,1,fp);
  37.  fseek(fp,length-6,SEEK_CUR); // to end of chunk
  38. return 0; }
  39.  
  40.  
  41. word write_3ds ( mdl_object *obj, byte *filename ) {
  42.   dword location;
  43.   FILE *fp;
  44.  
  45.   fp = fopen ( filename, "wb" );
  46.   if ( !fp ) {
  47.      printf("unable to open .3ds file \"%s\"\n",filename);
  48.      exit(1);
  49.   }
  50.   location = start_chunk ( fp, MAGIC );
  51.   // write all data below
  52.     
  53.   write_ver   ( fp, 3 );
  54.   write_mesh  ( fp, obj );
  55.   // write length
  56.   end_chunk ( fp, location );
  57.   fclose(fp);
  58. return 0; }
  59.  
  60.  
  61.  
  62. word write_ver ( FILE *fp, dword ver ) {
  63. dword location;
  64.  location = start_chunk ( fp, VERSION );
  65.   fwrite(&ver,4,1,fp);
  66.  end_chunk ( fp, location );
  67. return 0; }
  68.  
  69.  
  70.  
  71. word write_mesh ( FILE *fp, mdl_object *obj ) {
  72. dword location;
  73.  word findex; // frame index
  74.  location = start_chunk ( fp, MESH );
  75.  
  76.  // install loop here to write all frames
  77.  for ( findex=0; findex< obj->head.frame_num; findex++ ) {
  78.     write_object ( fp, obj, findex );
  79.  printf("wrote frame %u\n",findex);
  80.  } // end for
  81.  end_chunk ( fp, location );
  82. return 0; }
  83.  
  84.  
  85. word write_object ( FILE *fp, mdl_object *obj, dword findex ) {
  86. dword location;
  87. dword index;
  88.  location = start_chunk ( fp, OBJECT );
  89.   // write name
  90.   index=0;
  91.   do {
  92.    fwrite(&obj->frame_ptr[findex].name[index],1,1,fp);
  93.    index++;
  94.   } while ( obj->frame_ptr[findex].name[index-1] && ( index < 256 ) );
  95.   // write data
  96.  
  97.   write_triobj ( fp, obj, findex );
  98.  
  99.  end_chunk ( fp, location );
  100. return 0; }
  101.  
  102.  
  103.  
  104. word write_triobj ( FILE *fp, mdl_object *obj, dword findex ) {
  105. dword location;
  106.  location = start_chunk ( fp, TRIOBJ );
  107.   write_verts  ( fp, obj, findex );
  108.   write_tverts ( fp, obj );
  109.   write_faces  ( fp, obj ); // no frame index needed
  110.  end_chunk ( fp, location );
  111. return 0; }
  112.  
  113.  
  114.  
  115.  
  116. word write_verts   ( FILE *fp, mdl_object *obj, dword findex ) {
  117. dword location;
  118.  float x,y,z;
  119.  word vert_num;
  120.  word v0;
  121.  
  122.  location = start_chunk ( fp, VERTS );
  123.   //
  124.  vert_num = obj->head.vert_num;
  125.  fwrite(&vert_num,2,1,fp);
  126.  
  127.  for ( v0=0; v0< vert_num; v0++ ) {
  128.   x = obj->frame_ptr[findex].vert_ptr[v0].x *
  129.          obj->head.scale.x + obj->head.origin.x + obj->head.eye_pos.x;
  130.   y = obj->frame_ptr[findex].vert_ptr[v0].y *
  131.          obj->head.scale.y + obj->head.origin.y + obj->head.eye_pos.y;
  132.   z = obj->frame_ptr[findex].vert_ptr[v0].z *
  133.          obj->head.scale.z + obj->head.origin.z + obj->head.eye_pos.z;
  134.   fwrite(&y,4,1,fp);
  135.   x = -x;
  136.   fwrite(&x,4,1,fp);
  137.   fwrite(&z,4,1,fp);
  138.  } // end v0
  139.  
  140.  end_chunk ( fp, location );
  141. return 0; }
  142.  
  143.  
  144.  
  145.  
  146. word write_faces   ( FILE *fp, mdl_object *obj ) {
  147. dword location;
  148.  word face_num;
  149.  word v0,v1,v2;
  150.  word flags = 1030; // not sure what this represents
  151.  word f0;
  152.  
  153.  location = start_chunk ( fp, FACES );
  154.  face_num = obj->head.tri_num;
  155.  fwrite(&face_num,2,1,fp);
  156.  //printf("writing %u faces\n",face_num );
  157.  
  158.  for ( f0=0; f0< face_num; f0++ ) {
  159.   v2 = obj->tri_ptr[f0].vert[0]; // v0 swapped for v2 ( normal fix ) 
  160.   v1 = obj->tri_ptr[f0].vert[1];
  161.   v0 = obj->tri_ptr[f0].vert[2];
  162.   fwrite(&v0,2,1,fp);
  163.   fwrite(&v1,2,1,fp);
  164.   fwrite(&v2,2,1,fp);
  165.   fwrite(&flags,2,1,fp);
  166.   //printf("wrote face %u %u %u - %u\n",v0,v1,v2,flags);
  167.  } // end f0
  168.  
  169.  end_chunk ( fp, location );
  170. return 0; }
  171.  
  172.  
  173.  
  174. word write_tverts  ( FILE *fp, mdl_object *obj ) {
  175. dword location;
  176.  word tvert_num;
  177.  word t0;
  178.  float u,v;
  179.  
  180.  location = start_chunk ( fp, TVERTS );
  181.  tvert_num = obj->head.vert_num;
  182.  fwrite(&tvert_num,2,1,fp);
  183.  //printf("writing %u tverts\n",tvert_num);
  184.  
  185.  for ( t0=0; t0< tvert_num; t0++ ) {
  186.   u =  obj->tvert_ptr[t0].s;
  187.  
  188.   if ( u > (obj->head.skin_width/2) )  // back to one side
  189.      u -= (obj->head.skin_width/2);
  190.  
  191.   u /= obj->head.skin_width;
  192.    v =  obj->tvert_ptr[t0].t;
  193.  
  194.    // flip here for proper texmaps
  195.      v -=  obj->head.skin_height/2;
  196.      v =  -v;
  197.      v +=  obj->head.skin_height/2;
  198.    // flip done
  199.  
  200.    v /= obj->head.skin_height;
  201.   fwrite(&u,4,1,fp);
  202.   fwrite(&v,4,1,fp);
  203.  
  204.   //printf("tvert %u: %8.2f %8.2f\n",t0,u,v);
  205.  } // end t0
  206.  end_chunk ( fp, location );
  207. return 0; }
  208.  
  209.  
  210.  
  211.